#define MaxTypeLen 100
#define HashSize 4
#define MaxPar 10
#define MaxFunctionLength 500
/***************************************************************************
 We have intoduced three variables to take care of all type of declaration : type_qualifier(qualifier) , type_specifier(specifier) , 
    storage_class_specifier(storage)
    
    qualifier 
	1 ------ CONST
	2 ------ VOLATILE
	
	 storage
	1 ------ TYPEDEF
	2 ------ EXTERN
	3 ------ STATIC
	4 ------ AUTO
	5 ------ REGISTER
	
    specifier 
	1 ------ VOID
	2 ------ CHAR
	3 ------ SHORT
	4 ------ INT
	5 ------ LONG
	6 ------ FLOAT
	7 ------ DOUBLE
	8 ------ SIGNED
	9 ------ UNSIGNED
	 ------ struct_or_union_specifier
	10 ----- enum_specifier
	11 ----- TYPE_NAME
	12------Struct
	13------Union
	
    type = qualifier + storage*10 + specifier*100 +// isFunction*1000 + isPointer*10000
 *******************************************************************************/

/* Abhi ke liye sirf single level pointer, upar likhe specifier aur function without overloading implement kar rahe hain... */

//typeSpecifier 
#define Int 		0
#define Char 		1
#define Float		2
#define Double		3
#define Long		4
#define Void		5


struct SymEntry {
  char *id;  
  int scope;  
  int type;
  //char *typeName;
  int keywordval;	//UNION, INT , etc.
  int linenum;
  int isPointer;
  int isArray;
  int ArrayLimit;
  int isFunction;
  int offset;
  int width;
  int numParameters;
  struct Attribute *ParameterList[MaxPar]; //Will hold parameter List if the isFunction flag=1;
  struct SymEntry *next;
};


struct Attribute {
	//char *type; 
	char *id;
	int type;
	int isArray;		// True if variable is array
	int ArrayLimit;	// upper limit of array (valid if DIMENSION is true)
	int width;
	int isPointer;
	int qualifier;
	int specifier;
	int storage;	
	int scope;		//ISKI ZARURAT HI KYA HAI AS IN ATTRIBUTES!!!!
	long long IntConstValue;		// because this g++ compiler set 4 byte for long but we are setting 8 bytes
	int IntConst;
	double FloatConstValue;			// to store the value of double or float      
	char *StringValue;
	int isFunction;//   
	int numParameters;
	int isString;
	int offset;
	char *code;
	char *icode;
	struct Attribute *ParameterList[MaxPar]; //Will hold parameter List if the isFunction flag=1;	
};

union VALUE	
{
	int intValue;
	long longIntValue;
	float floatValue;
	double doubleValue;
	char charValue;
	char *string;
};

/*struct ScopeEntry{	//---used in original

	char *id; 	//Identifier name
	union VALUE v;	//Its value
	char *scope;	//Its scope
	char *labelScope;	//If idName is a lebel, scope contains "label". So this is the scope to which the label belongs.
	char *type;	//Its type
	int width;
	struct ScopeEntry *next;	//pointer to next node
	int Const;			// store whether identifier is const or not
	int ptrConst;		// store const pointer 
	int doubleptr;			//nkbansal
	int doubleptrConst;			//nkbansal
	int IntConst;		//enumerated identifiers are Integer constant can be used any where just like literal constants
	int stackOffset;//	   
	int heapOffset;//    
	//int width;	//   
	int ptr;
	int functionFlag;
	int functionOverloading;//free slot index of overloaded functions put at same node in scopeTable
	struct ScopeEntry *parameterList[10];//parameter list
	int definitionFlag[10];//has the function been declared
	char * returntype[10];
	int functionDeclareFlag;
	int activationRecordSize;
};*/


struct SymTableNode {
  int scope;  
  char *name;
  struct SymEntry *table[HashSize];
  struct SymTableNode *next;
};
/*struct ScopeTableNode {		//---used in original
  char *scope;  
  struct ScopeEntry *table[HashSize];
  struct ScopeTableNode *next;
};*/

struct SymTableNode *global[2];
struct SymTableNode *tail[2];  
/*struct ScopeTableNode *Global;		//---used in original
struct ScopeTableNode *Tail;  */

struct SymTableNode *CreateNewSymTableNode();
struct SymEntry* lookup(char *,int);
struct SymEntry *InsertSymTable(char *,int,int,int);
void PopSym(int);

/*void InitializeScopeTable();				//----used in original
struct ScopeEntry *InsertScopeTable(char *name,char* currentScope,char* typ);
struct ScopeEntry* Scopelookup(char *name);
struct ScopeTableNode *CreateNewScopeTableNode();*/
struct Attribute * initAttr(struct Attribute*);
struct Attribute *PassAttribute(struct Attribute *a1);
struct Attribute *PassSymEntry(struct SymEntry *a1);
//struct Attribute *temp_inherted;
int CheckBeforeMerge(struct Attribute* a1,struct Attribute* a2);
struct Attribute * MergeAttributes3Code(struct Attribute* a1,struct Attribute* a2);
void PrintAttribute(struct Attribute *a);
void PrintSymEntry(struct SymEntry *a);
void PrintSymTable();